/**
 * Copyright (C) 2009 Marcel Urbanek
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.urbiworx.sugar;

import java.util.Collection;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.context.FacesContext;

import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Scope;

public abstract class JSFScopeAbstract implements Scope {

	public <T> Provider<T> scope(final Key<T> aKey,final Provider<T> aProvider) {
		return new Provider<T>(){
			public T get(){	
				Map <Key,Object> map=getSugarMap();
				T tempObj=(T)map.get(aKey);
				if (tempObj==null)
				{
					tempObj=aProvider.get();
					map.put(aKey, tempObj);
				}		
				if (ClientScopePhaseListener.isRenderClientScope())
				{
					SugarConfigurationEntry entry=SugarScopeHelper.convertKeyToSugarEntry(aKey);
					if (entry!=null&&entry.isClient())
					{
						Collection<SugarConfigurationEntry> clientList=SugarScopeHelper.getClientList();
						if(!clientList.contains(entry))
						{
							UIForm form=getForm(FacesContext.getCurrentInstance().getViewRoot());
							addClientOutput(form,entry);
							clientList.add(entry);
						}
						
					}	
				}
				return tempObj;
			}
		};
	}
	protected abstract Map <Key,Object> getSugarMap();
	
	private UIForm getForm(UIComponent component)
	{
		if (component instanceof UIForm)
		{
			return (UIForm)component;
		}
		for (UIComponent curComponent:component.getChildren())
		{
			UIForm form=getForm(curComponent);		
			if (form!=null)
			{
				return form;
			}
		}
		return null;
	}

	
	private void addClientOutput(UIForm form,SugarConfigurationEntry entry) {
		form.getChildren().add(new ClientStateOutput(entry));
	}



}
